package com.example.web.aspect;

import com.example.web.annotation.RequiresPermission;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 权限切面
 */
@Aspect
@Component
public class PermissionAspect {

    /**
     * 环绕通知，拦截带有RequiresPermission注解的方法
     */
    @Around("@annotation(com.example.web.annotation.RequiresPermission)")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        // 获取方法签名
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        
        // 获取方法上的RequiresPermission注解
        RequiresPermission annotation = method.getAnnotation(RequiresPermission.class);
        if (annotation == null) {
            // 如果没有注解，直接执行方法
            return point.proceed();
        }
        
        // 获取注解中的权限值
        String permission = annotation.value();
        RequiresPermission.Logical logical = annotation.logical();
        
        // 检查权限
        if (hasPermission(permission, logical)) {
            // 有权限，执行方法
            return point.proceed();
        } else {
            // 无权限，抛出权限异常
            throw new com.example.web.exception.PermissionException();
        }
    }
    
    /**
     * 检查是否有权限
     * @param permission 权限字符串
     * @param logical 逻辑类型
     * @return 是否有权限
     */
    private boolean hasPermission(String permission, RequiresPermission.Logical logical) {
        // 获取当前用户的认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return false;
        }
        
        // 获取当前用户的权限列表
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        List<String> permissions = authorities.stream()
                .map(GrantedAuthority::getAuthority)
                .collect(Collectors.toList());
        
        // 超级管理员(ROLE_ADMIN)拥有所有权限
        if (permissions.contains("ROLE_ADMIN")) {
            return true;
        }
        
        // 判断是否有权限
        if (logical == RequiresPermission.Logical.AND) {
            // 逻辑AND：所有权限都要有
            return Arrays.stream(permission.split(","))
                    .allMatch(permissions::contains);
        } else {
            // 逻辑OR：有一个权限即可
            return Arrays.stream(permission.split(","))
                    .anyMatch(permissions::contains);
        }
    }
}